// Copyright (c) 2022 Presto Labs Pte. Ltd.
// Author: qiang

#pragma once

#include <string>

#include "coin2/exchange/base/api_base/asio_http_context.h"
#include "coin2/exchange/base/order/order.h"
#include "coin2/exchange/crypto_common/api_util/auth_key.h"
#include "coin2/exchange/crypto_common/api_util/rate_tracker.h"

namespace coin2::exchange::order {
class CryptoRestParams;
class OrderConnectionConfig;
class CryptoFuturesRestParams;
}  // namespace coin2::exchange::order

namespace coin2::exchange::base::order {
struct OrderExecution;
struct OrderSpec;
}  // namespace coin2::exchange::base::order

class CryptoV1NativePrivateClient : public coin2::exchange::base::order::NativePrivateClient {
 public:
  using Base = coin2::exchange::base::order::NativePrivateClient;
  using NativeClientConfig = coin2::exchange::order::OrderConnectionConfig;
  using OrderExecution = coin2::exchange::base::order::OrderExecution;
  using OrderSpec = coin2::exchange::base::order::OrderSpec;
  using IOrderContext = coin2::exchange::base::order::IOrderContext;
  using HttpContextPtr = std::shared_ptr<AsioHttpContext>;
  using ActionType = coin2::exchange::base::order::NativePrivateClient::ActionType;
  using RestParams = coin2::exchange::order::CryptoFuturesRestParams;
  using CryptoRateTracker = coin2::exchange::crypto_common::api_util::CryptoRateTracker;

 public:
  std::shared_ptr<AsioHttpContext> SubmitOrderExecution(const OrderExecutionProto& order);
  std::shared_ptr<AsioHttpContext> SubmitRestQuery(const RestQueryProto& query);

 public:
  explicit CryptoV1NativePrivateClient(
      const MarketExchangeApi& mea,
      const NativeClientConfig& config);

  HttpContextPtr QueryAccountBalance();
  HttpContextPtr QueryOpenOrders();
  HttpContextPtr QueryHistOrders(const RestParams& params);
  HttpContextPtr QueryTrades(const RestParams& params);

  HttpContextPtr PlaceOrder(const RestParams& params);
  HttpContextPtr CancelOrder(const RestParams& params);
  HttpContextPtr CancelAllOrder(const RestParams& params);

  HttpContextPtr PlaceOrderNorm(const OrderExecution&) override;
  HttpContextPtr CancelOrderNorm(const OrderExecution&) override;

  RestParams GetRestOrderParams(const OrderSpec& order_spec, int64_t proc_order_id);
  RestParams GetRestCancelParams(const IOrderContext& order_context);

  void Print();
  void Print1();

  CryptoRestAuth* GetAuth() const override {
    return dynamic_cast<CryptoRestAuth*>(Base::GetAuth());
  }

  std::string DebugString();

 private:
  const std::string path_query_account_balance_ = "/v1/private/user-balance";
  const std::string path_query_open_orders_ = "/v1/private/get-open-orders";
  const std::string path_query_hist_orders_ = "/v1/private/get-order-history";
  const std::string path_query_trades_ = "/v1/private/get-trades";
  const std::string path_place_order_ = "/v1/private/create-order";
  const std::string path_cancel_order_ = "/v1/private/cancel-order";
  const std::string path_cancel_orders_ = "/v1/private/cancel-all-orders";
  bool is_first_query_account_balance_ = true;
  CryptoRateTracker* local_rate_tracker_;
  std::unordered_map<std::string, int32_t> api_block_info_;
  std::unordered_map<std::string, int32_t> api_req_info_;
  int64_t start_time_;
};
